# -*- coding: utf-8 -*-
from __future__ import print_function	#used in python 2
from operator import add,sub,mul
from fractions import Fraction
from itertools import product,combinations_with_replacement
#import sys,io
#sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')	#to use in utf8 console env, comment this line to use in cmd

oper={
	'+':add,
	'-':sub,
	'×':mul,
	'/':Fraction
}
class Node:
	def __init__(self,opr,left,right):
		self.opr,self.left,self.right=opr,left,right
	def reduce(self):
		return oper[self.opr](self.left.reduce() if isinstance(self.left,Node) else self.left,
			self.right.reduce() if isinstance(self.right,Node) else self.right)
	def __repr__(self):
		l=''.join(('(',repr(self.left),')')) if isinstance(self.left,Node) else repr(self.left)
		r=''.join(('(',repr(self.right),')')) if isinstance(self.right,Node) else repr(self.right)
		return "".join((l,self.opr,r))

class parseNode:
	def __init__(self,node=None):
		if node:
			self.oprArray,self.children=\
				[node.opr,],\
				[parseNode(node.left) if isinstance(node.left,Node) else node.left,\
				parseNode(node.right) if isinstance(node.right,Node) else node.right]
	def __repr__(self):
		def _toString_(child,opr):
			if isinstance(child,parseNode):
				if not (opr in set(['+','-']) and child.oprArray[0] in set(['×','/'])):
					return ''.join(('(',repr(child),')'))
			return repr(child)
		l=len(self.oprArray)
		r=[]
		for i in range(l):
			child,op=self.children[i],self.oprArray[i]
			r.append(_toString_(child,op))
			r.append(op)
		last=self.children[l]
		r.append(_toString_(last,self.oprArray[-1]))
		return ''.join(r)
	def reduce(self):
		data=[v.reduce() if isinstance(v,parseNode) else v for v in self.children]
		leng=len(self.oprArray)
		for i in range(leng):
			d=oper[self.oprArray[i]](data[i],data[i+1])
			data[i+1]=d
		return data[-1]
	#	http://www.24theory.com/theory/
	def flatten(self,debug=False):
		def _flatten_(node):	#只有(+-)或者(×/)可以放同一级，a+b×c隐含表达为a+(b×c)
			change=False
			if debug:
				print('0',node)
			for child in node.children:
				if isinstance(child,parseNode):
					if child.flatten():change=True
			leng=len(node.oprArray)
			#commutativity
			if debug:
				print('1',node)
			def _exchange_(index):
				l,r=node.children[index],node.children[index+1]
				il,ir=isinstance(l,parseNode),isinstance(r,parseNode)
				c=False
				if (not il) and (not ir) and l<r:
					c=True
				elif (not il) and ir:
					c=True
				elif il and ir:
					if ord(l.oprArray[0][0])<ord(r.oprArray[0][0]):
						c=True
					elif ord(l.oprArray[0][0])==ord(r.oprArray[0][0]):
						if l.children[0]<r.children[0]:
							c=True
						elif l.children[0]==r.children[0]:
							if l.children[1]<r.children[1]:
								c=True
				if c:
					node.children[index],node.children[index+1]=node.children[index+1],node.children[index]
					return True
				return False
			for i in range(leng):
				opr=node.oprArray[i]
				if opr in set(['+','×']):
					if _exchange_(i):change=True
				elif i<leng-1:
					opr2=node.oprArray[i+1]
					if opr2 in set(['-','/']):
						if _exchange_(i+1):change=True
					else:
						node.oprArray[i],node.oprArray[i+1]=node.oprArray[i+1],node.oprArray[i]
						node.children[i+1],node.children[i+2]=node.children[i+2],node.children[i+1]
						change=True
			if leng==1:
				#-1×-1
				l,r=node.children[0],node.children[1]
				if node.oprArray[0]=='×' and isinstance(l,parseNode) and isinstance(r,parseNode):
					if l.oprArray[0]=='-' and l.reduce()<0:
						l.children[0],l.children[1]=l.children[1],l.children[0]
						r.children[0],r.children[1]=r.children[1],r.children[0]
						change=True
				#1--1
				elif node.oprArray[0]=='-' and isinstance(r,parseNode):
					if r.reduce()<0 and len(r.oprArray)==1:
						if r.oprArray[0]=='-':
							r.children[0],r.children[1]=r.children[1],r.children[0]
							node.oprArray[0]='+'
							change=True
						elif r.oprArray[0] in set(['×','/']):
							for child in r.children:
								if isinstance(child,parseNode):
									if child.oprArray[0]=='-':
										child.children[0],child.children[1]=child.children[1],child.children[0]
										node.oprArray[0]='+'
										change=True
										break
			#associativity
			if debug:
				print('2',node)
			group={
				'+':set(['+','-']),
				'-':set(['+','-']),
				'×':set(['×','/']),
				'/':set(['×','/'])
			}
			rev_group={
				'+':'+',
				'-':'+',
				'×':'×',
				'/':'×'
			}
			def _flat_(father,child,index,left=False):
				index_op=index if left else index+1
				child.oprArray.reverse()
				for o in child.oprArray:
					father.oprArray.insert(index_op,o)
				child.children.reverse()
				for n in child.children:
					father.children.insert(index_op+1,n)
				del father.children[index_op]
			for i in range(len(node.oprArray)):
				opr=node.oprArray[i]
				if opr in set(['+','×']):
					r=node.children[i+1]
					if isinstance(r,parseNode):
						if set(r.oprArray)<=group[opr]:
							_flat_(node,r,i)
							change=True
				l=node.children[i]
				if isinstance(l,parseNode):
					if i==0 or node.oprArray[i-1]==rev_group[opr]:
						if set(l.oprArray)<=group[opr]:
							_flat_(node,l,i,True)
							change=True
			#exchangeability
			if debug:
				print('3',node)
			revop={
				'+':'-',
				'-':'+',
				'×':'/',
				'/':'×'
			}
			def _rev_flat_(father,child,index_op,left=False):
				for i in range(len(child.oprArray)):
					child.oprArray[i]=revop[child.oprArray[i]]
				_flat_(father,child,index_op,left)
			for i in range(len(node.oprArray)):
				opr=node.oprArray[i]
				if opr in set(['-','/']):
					r=node.children[i+1]
					if isinstance(r,parseNode):
						if set(r.oprArray)<=group[opr]:
							_rev_flat_(node,r,i)
							change=True
			#less negativity
			if debug:
				print('4',node)
			if node.oprArray[0]=='-':
				last_child=node.children[-1]
				if isinstance(last_child,parseNode):
					l=last_child.children[0]
					if isinstance(l,parseNode):
						if l.oprArray[0]=='-':
							l.children.reverse()
							node.oprArray[0]='+'
							change=True
			#×/ 1
			if debug:
				print('5',node)
			for i in range(len(node.oprArray)):
				opr=node.oprArray[i]
				if opr=='/':
					r=node.children[i+1]
					rvar=r.reduce() if isinstance(r,parseNode) else r
					if rvar==1:
						node.oprArray[i]='×'
						change=True
			#× 1
			if debug:
				print('6',node)
			def _find1_(father):
				ones=[]
				for child in father.children:
					if isinstance(child,parseNode):
						for i in range(len(child.oprArray)):
							if child.oprArray[i]=='×':
								r=child.children[i+1]
								rvar=r if not isinstance(r,parseNode) else r.reduce()
								if rvar==1:
									ones.append(child.children[i+1])
									child.children[i+1]=False
									child.oprArray[i]=False
						if child.oprArray[0]=='×':
							l=child.children[0]
							lvar=l if not isinstance(l,parseNode) else l.reduce()
							if lvar==1:
								ones.append(child.children[0])
								child.children[0]=False
								child.oprArray[0]=False
						child.children,child.oprArray=[i for i in child.children if i],[i for i in child.oprArray if i]
				return ones
			if node.oprArray[0] in set(['+','-']):
				find=_find1_(node)
				if len(find)!=0:
					for i in range(len(node.oprArray)+1):
						child=node.children[i]
						if isinstance(child,parseNode):
							if len(child.oprArray)==0:
								node.children[i]=child.children[0]
					newnode=parseNode()
					newnode.children,newnode.oprArray=node.children,node.oprArray
					node.children,node.oprArray=[newnode,],[]
					for i in find:
						node.children.append(i)
						node.oprArray.append('×')
					change=True
			def _findaa_(father):
				for child in father.children:
					if isinstance(child,parseNode):
						if child.oprArray[0]=='×' and child.oprArray[-1]=='/':
							if child.children[0]==child.children[2]:
								result=child.children[2]
								del child.children[2]
								del child.children[0]
								return result
							elif child.children[1]==child.children[2]:
								result=child.children[2]
								del child.children[2]
								del child.children[1]
								return result
				return -1
			if len(node.oprArray)==1 and node.oprArray[0] in set(['+','-']):
				find=_findaa_(node)
				if find!=-1:
					for i in range(2):
						if isinstance(node.children[i],parseNode):
							if len(node.children[i].children)==1:
								node.children[i]=node.children[i].children[0]
								break
					newnode=parseNode()
					newnode.children,newnode.oprArray=node.children,node.oprArray
					node.children,node.oprArray=[newnode,find,find],['×','/']
					change=True
			#[a,b,c,c]
			if debug:
				print('7',node)
			leng=len(node.oprArray)
			if len(node.children)==4:
				if node.children[2]==node.children[3]==1 and set(node.oprArray)==set(['×',]):
					newnode=parseNode()
					newnode.children,newnode.oprArray=node.children[0:2],node.oprArray[0:1]
					k=node.children[2]
					node.children,node.oprArray=[newnode,k,k],['+','-']
					change=True
				elif node.oprArray[0] in set(['×','/']):
					div,strip={},False
					for i in range(leng):
						if node.oprArray[i]=='/':
							if not isinstance(node.children[i+1],parseNode):
								div[node.children[i+1]]=i
					for i in range(leng):
						if node.oprArray[i]=='×':
							if not isinstance(node.children[i+1],parseNode):
								if node.children[i+1] in div:
									strip=node.children[i+1]
									node.oprArray[div[strip]]=False
									node.oprArray[i]=False
									node.children[div[strip]+1]=False
									node.children[i+1]=False
									break
					if not strip:
						if node.oprArray[0]=='×':
							if not isinstance(node.children[0],parseNode):
								if node.children[0] in div:
									strip=node.children[0]
									node.oprArray[div[strip]]=False
									node.oprArray[0]=False
									node.children[div[strip]+1]=False
									node.children[0]=False
					if strip:
						newnode=parseNode()
						newnode.children,newnode.oprArray=[i for i in node.children if i],[i for i in node.oprArray if i]
						node.children,node.oprArray=[newnode,strip,strip],['+','-']
						chaneg=True
			elif len(node.children)==3 and node.children[1]==node.children[2] and isinstance(node.children[0],parseNode):
				if node.oprArray[1]=='/' or (node.children[2]==1 and set(node.oprArray)==set(['×',])):
					node.oprArray=['+','-']
					change=True
			elif len(node.oprArray)==1 and node.oprArray[0]=='×' and isinstance(node.children[0],parseNode):
				child=node.children[0]
				if len(child.oprArray)==2:
					if child.oprArray[0]=='+' and child.oprArray[1]=='-':
						if child.children[1]==child.children[2]:
							l,k=child.children[0],child.children[1]
							node.children[0]=l
							newnode=parseNode()
							newnode.oprArray,newnode.children=node.oprArray,node.children
							node.children,node.oprArray=[newnode,k,k],['+','-']
							change=True
						elif child.children[0]==child.children[2]:
							l,k=child.children[1],child.children[2]
							node.children[0]=l
							newnode=parseNode()
							newnode.oprArray,newnode.children=node.oprArray,node.children
							node.children,node.oprArray=[newnode,k,k],['+','-']
							change=True
			if debug:
				print('9',node)
			return change
		change=False
		while _flatten_(self):
			change=True
		return change

#permutation code from http://stackoverflow.com/a/6571976
def permutations2(tuple):
	ls=list(tuple)
	n=len(ls)
	#list.sort()
	def next_permutations(l):
		last=n-1
		while last>0:
			if l[last-1]<l[last]:break
			last-=1
		if last>0:
			small=l[last-1]
			big=n-1
			while l[big]<=small:big-=1
			l[last-1],l[big]=l[big],small
		i=last
		j=n-1
		while i<j:
			l[i],l[j]=l[j],l[i]
			i+=1
			j-=1
		return last>0
	yield ls
	while(next_permutations(ls)):
		yield ls

def calc(list,debug=False):
	def array2node(digis,oprs,priors):
		node,ls,op,pr=None,digis[:],[o for o in oprs],priors[:]
		for i in range(3):
			p=pr[i]
			node=Node(op[p],ls[p],ls[p+1])
			ls[p]=node
			del ls[p+1]
			del op[p]
			for j in range(i,3):
				if pr[j]>p:
					pr[j]-=1
		return node
	def pass1():
		for digis in permutations2(list):
			for opers in product(oper,repeat=3):
				for prior in permutations2([0,1,2]):
					try:
						node=array2node(digis,opers,prior)
						if node.reduce()==24:yield node
					except ZeroDivisionError:
						continue
	result=set([])
	for i in pass1():
		pNode=parseNode(i)
		pNode.flatten(debug)
		result.add(repr(pNode))
	return result

def test():
	print('#\tInput',end='')
	for i in range(11):
		print('\tSolution',i+1,sep='',end='')
	print()
	count,all=0,0
	for i in combinations_with_replacement(range(1,14),4):
		all+=1
		print(all,end='\t')
		print(*i,end='\t')
		r=calc(i)
		if len(r)==0:
			print('No solution...')
		else:
			count+=1
			print(*r,sep='\t')
	print(count,'out of',all,'have solution(s)')

test()
#print(calc([2,3,3,12],True))